﻿using System.Text;

namespace Teal.Compiler {

    /// <summary>
    /// 表示一个标记。
    /// </summary>
    public sealed class Token {

        /// <summary>
        /// 用于支持多个对象组成一个单链表。
        /// </summary>
        public Token next;

        /// <summary>
        /// 获取当前标记的类型。
        /// </summary>
        public TokenType type;

        /// <summary>
        /// 获取当前标记的起始位置。
        /// </summary>
        public Location startLocation;

        /// <summary>
        /// 获取当前标记的结束位置。
        /// </summary>
        public Location endLocation;

        /// <summary>
        /// 获取存储当前标记内容的缓存。此属性只对特定的标记类型（如字符串）有效。
        /// </summary>
        public StringBuilder buffer = new StringBuilder();

        /// <summary>
        /// 支持对于特定的标记存储额外的数据。
        /// </summary>
        public float tag;

        /// <summary>
        /// 判断当前标识之前是否存在换行符。
        /// </summary>
        public bool hasLineTerminatorBeforeStart;

        /// <summary>
        /// 获取当前标识之前的文档注释。
        /// </summary>
        public DocComment docComment;

        /// <summary>
        /// 返回表示当前 <see cref="T:System.Object"/> 的 <see cref="T:System.String"/>。
        /// </summary>
        /// <returns>
        /// 	<see cref="T:System.String"/>，表示当前的 <see cref="T:System.Object"/>。
        /// </returns>
        public override string ToString() {
            switch (type) {
                case TokenType.stringLiteral:
                    return Utility.escapeString(buffer.ToString());
                case TokenType.hexIntLiteral:
                    return "0x" + buffer.ToString();
                case TokenType.intLiteral:
                case TokenType.floatLiteral:
                case TokenType.identifier:
                    return buffer.ToString();
                default:
                    return type.getName();
            }
        }

        /// <summary>
        /// 复制当前标记。
        /// </summary>
        /// <returns></returns>
        public Token clone() {
            return new Token() {
                type = type,
                buffer = type.hasData() ? Utility.clone(buffer) : new StringBuilder(),
                startLocation = startLocation,
                endLocation = endLocation,
                hasLineTerminatorBeforeStart = hasLineTerminatorBeforeStart,
            };
        }

    }

}
